iT邦幫忙

2021 iThome 鐵人賽

DAY 23
0
永豐金融APIs

錢進!永豐金融APIs程式串接實戰最前線系列 第 23

Day23 - [豐收款] 以Django Web框架實作永豐API線上支付模擬情境(4) - 信用卡刷卡結果

  • 分享至 

  • xImage
  •  

昨天寫完兩種付款方式,有提到原先信用卡刷卡後的結果導回頁ReturnURL我們還沒實作,今天就把這一頁完成。

先說明一下,信用卡刷卡時,不會立即得到結果,會透過我們在建立訂單時傳入的ReturnURL參數,待轉入永豐線上刷卡頁面後,會再透過這個網址導回我們的電商結果頁。細部流程如下

流程說明

  1. [電商] 呼叫永豐API,建立信用卡付款方式的訂單,從response取回card_pay_url結果,我們將顧客導到這個網址去刷卡
  2. [永豐] 在永豐的網頁進行刷卡,因此使用者的信用卡機敏資訊不會留在電商平台上
  3. [永豐] 進行信用卡刷卡處理,先無論結果,完成後會將PayToken值傳入ReturnURL
  4. [電商] 這時候會透過ReturnURL將PayToken值帶回,我們將此值取出
  5. [電商] 以PayToken呼叫永豐API訊息查詢服務(OrderPayQuery)
  6. [永豐] 回傳付款狀態相關資訊
  7. [電商] 將付款狀態結果顯示於頁面上,會分別顯示刷卡成功以及刷卡失敗不同狀態的資訊,若刷卡失敗我們可再提供一次刷卡連結果顧客

View的card_return修改

先前我們有寫過View中的card_return(),當時只驗證一些資訊往來正不正確,現在要作一些小調整,但幅度不大。

def card_return(request):
    pay_token_dic = {"PayToken": request.POST.get("PayToken"), "ShopNo": request.POST.get("ShopNo")}
    create_new_paytoken(pay_token_dic["PayToken"])
    result = update_order_by_paytoken(pay_token_dic)
    return render(request, 'order/card_return.html', result)
程式說明

主要是當初我們呼叫update_order_by_paytoken()時,沒有回傳值,我們希望把整理過必要的資訊回傳值拿回來,在等一下的Template中作為判斷以及顯示相關結果的訊息

而另外我們把當初的HttpResponse改成了render方式導引到新準備的order/card_return.html中。

Model中的update_order_by_paytoken()修改

def update_order_by_paytoken(paytoken_json):
    result = {}
    if paytoken_json:
        pay_token = paytoken_json["PayToken"]
        create_new_paytoken(pay_token)

        paytoken_api = QueryByPaytokenMessage()
        paytoken_api.set_paytoken_json(paytoken_json)
        resp = ResponsePayToken(paytoken_api.send_query(), paytoken_api.hash_id)
        print("-- Response: " + str(resp.dec_resp_json))

        order = Payment.objects.get(order_no=resp.orderno)
        order.pay_status = resp.status
        order.pay_token = pay_token
        order.lm_time = datetime.now()
        order.save()

        result["order_no"] = order.order_no
        result["status_code"] = order.pay_status
        if order.pay_status == "S":
            result["pay_status"] = "刷卡成功"
        else:
            result["pay_status"] = "刷卡失敗"
        result["card_pay_url"] = order.card_pay_url

        print(" Update Order Successfully.")
    else:
        print(" Update Order Fail.")
    return result
程式說明

update_order_by_paytoken()中,我們主要準備了一個result作為回傳,把所需要的必要資訊整理成dictionary回傳回去,在這裡順便把pay_status中的代碼換成了可閱讀的顯示文字。

不過我必須再三強調,這樣的寫法並非產品等級的撰寫方法,這也不是在這系列文章中我打算實作的,那樣只會對主要要介紹永豐API的串接失焦了。但我們可以談一談可以怎麼做會比較好。

  1. 在Model裡面即使使用了原本代碼要轉成可閱讀文字,並不會直接這樣處理,無論你的網站一開始是不是單一語言,這種最終要顯示在UI上的文字,不會在Model裡直接替換,至少需考量到i18n多國語系。
  2. 即使沒有要做多國語系,這樣的UI文字替換,也不會在處理專職功能的商業邏輯中實作,好一點的方式會寫在回傳之後,再呼叫另一個專門處理代碼轉文字的Converter邏輯。
  3. 上面這個Converter,另一個呼叫階段可擺在View的那層來處理(我說的是View,不是Template),但不是在View層直接作代碼轉文字,而是在View那層"再呼叫處理轉換的邏輯",畢竟這個最終的內容是屬於偏UI的內容。

但為了範例方便,我們就直接在Model裡處理掉了,但這絕對不是最好的作法。

可以來看Template了

{% extends "base.html" %}

{% block title %}{{ title }}{% endblock %}

{% block body %}
<div id="app" class="row g-3 align-self-center">
<h1 class="display-4 text-center  mb-3 mt-5">信用卡刷卡結果</h1>
<p class="lead  text-center">感謝您使用永豐線上信用卡刷卡服務,以下是您的刷卡結果喔!</p>
<hr/>
<div class="container-fluid">
    <h3 class="mb-5">
      訂單號碼 <small class="text-muted">{{ order_no }}</small>
    </h3>
    <div class="border border-secondary rounded m-2 {% if status_code == 'S' %}bg-success{% else %}bg-danger{% endif %}
    text-white p-3">
        <h6>您的刷卡結果</h6>
        <p>
            <span class="primary fs-4">{{ pay_status }}</span>
        </p>
        {% if status_code != 'S' %}
            <a href="{{ card_pay_url }}" class="btn btn-light btn-lg" tabindex="-1" role="button" aria-disabled="true">再次使用永豐信用卡刷卡</a>
        {% endif %}

    </div>
    <br/><br/><br/><br/>
    <hr/>
    <div class="row mt-3">
        <div class="col text-center">
            <a href="{% url 'order_create_entrance' %}" class="btn btn-primary btn-lg" tabindex="-1" role="button" aria-disabled="true">繼續購買</a>
            &nbsp
            <a href="{% url 'my_orders' %}" class="btn btn-secondary btn-lg" tabindex="-1" role="button" aria-disabled="true">回到訂單</a>
        </div>
    </div>
</div>
</div>
{% endblock %}

{% block script %}
{% endblock %}
程式說明

刷卡結果當然就直接把剛剛上面談半天的刷卡結果的UI文字直接以{{ pay_status }}顯示出來。但我們希望在結果的二分世界中,以顏色來作明顯的區隔,因此就可以拿status_code結果代碼對刷卡成功或失敗改變顏色,這裡透過Bootstrap的基本幾個色調來調整div的背景顏色。

  • 成功:bg-success
  • 失敗:bg-danger

然後在失敗的時候,再次將刷卡網址按鈕附上,讓顧客有機會再執行一次刷卡。

以下就是執行的UI畫面,我們先刻意刷一次錯誤的卡片:
https://ithelp.ithome.com.tw/upload/images/20211008/20130354MSoC0oll9t.png

https://ithelp.ithome.com.tw/upload/images/20211008/20130354i9eWyjVYdN.png

所以立刻可以驗證那個重刷卡的按鈕,很好,又再次導入刷卡頁面,這次小心翼翼的輸入永豐提供給我們的測試信用卡卡號。如先前說明,因為非完全公開資料,為了怕有心人事拿去亂刷,我們就不在此公開這個測試頁面的內容和卡號。

https://ithelp.ithome.com.tw/upload/images/20211008/20130354N5EtYIUk6Q.png

https://ithelp.ithome.com.tw/upload/images/20211008/20130354ljybM9gioZ.png

刷卡成功了!看到綠綠顏色的就覺得很安全呀 (咦,股市的話好像就不是這種感覺...)

今天頭非常痛呀,原本想繼續寫訂單查詢狀態等的部份,但狀態不好只能寫到這裡了,明天再繼續吧。


上一篇
Day22 - [豐收款] 以Django Web框架實作永豐API線上支付模擬情境(3) - 兩種付款方式實作
下一篇
Day24 - [豐收款] 以Django Web框架實作永豐API線上支付模擬情境(5) - 我的訂單
系列文
錢進!永豐金融APIs程式串接實戰最前線30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言